6. K8S之资源对象
基础概念一
RC(Replication Controller)
- K8s集群中最早的保证Pod高可用的API对象。用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器退出,会自动创建新的
pod
来代替;而如果异常多出来的容器,也会自动回收。RS(Replication Set)
- 是新一代RC,提供同样的高可用能力,区别主要在于RS后来居上,能支持更多种类的匹配模式。(比如,根据pod的tags来批量管理,淘汰了RC)
Deployment
- 表示用户对K8s集群的一次更新操作。部署是一个比RS应用模式更广的API对象,可以是创建一个新的服务,更新一个新的服务,也可以是滚动升级一个服务。
- 一般建议使用Deployment 来自动管理 RS, 这样就无需担心跟其他机制的不兼容问题(比如RS 不支持 rolling-update 但是 Deployment 支持)
- Deployment 为Pod 和 RS 提供了一个声明式定义(declarative)方法, 用来代替以前的RC 来方便管理应用。 典型的场景包括:
- 定义Deployment 来创建Pod 和RS
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续 Deployment
RC、RS和Deployment只是保证了支撑服务的微服务Pod的数量,但是没有解决如何访问这些服务的问题。每个Service会对应一个k8s集群内部有效的虚拟IP,集群内部通过虚拟IP访问一个服务。
HPA (horizontal Pod Autoscaling)
HPA
仅使用于Deployment 和 RS, 在V1 版本中仅支持根据Pod
的CPU 利用率扩容,在v1alpha 版本中, 支持根据内存和用户自定义的metric 扩缩容。
StatefulSet
- StatefulSet 是为了解决有状态服务的问题(对应Deployments 和 ReplicaSets 是为了无状态服务而设计的),其应用场景包括:
- 稳定的持久化存储, 即
Pod
重新调度后还是能访问到相同的持久化数据, 基于PVC 来实现。 - 稳定的网络标志, 即
Pod
重新调度后其PodName 和HostName不变,基于HeadLess Serveice(即没有Cluster IP 的Service)来实现 - 有序部署, 有序扩展, 即 Pod是有顺序的, 在部署或者扩展的时候,要依据定义的顺序依次进行(即从0 到 N-1,在下一个Pod运行之前,所有之前的Pod 必须都是Running 和 Ready状态),基于 init containers 来实现。
- 有序收缩,有序删除(即从N-1 到 0)
- 稳定的持久化存储, 即
DaemonSet
- DaemonSet 确保全部(或者一些)Node上运行一个Pod的副本。 当有Node加入集群时, 也会为他们新增一个Pod。 当有Node从集群移除时, 这些Pod 也会被回收。 删除DaemonSet 将会删除它创建的所有Pod。
- 使用DaemonSet的一些典型用法:
- 运行集群存储 daemon, 例如在每个Node 上运行 glusterd, ceph。
- 在每个Node 上运行日志收集的daemon, 例如 fluentd、logstash。
- 在每个Node 上运行监控daemon, 例如 Prometheus Node Exporter。
Job
Job 负责批处理任务, 即仅执行一次的任务, 它保证批处理任务的一个或者多个Pod 成功结束。
Cron Job
周期性的运行任务,或者基于时间点运行任务(其实内部就是通过创建Job来完成任务的)。
基础概念二
网络通讯方式
K8S 的网络模型假定了所有的Pod 都在一个可以直接联通的扁平化的网络当中, 这在GCE(Google Compute Engine)里面是现成的网络模型,Kubernetes 假定这个网络已经存在。而在私有云里搭建 Kubernetes 集群, 就不能假定这个网络已经存在了。 我们需要自己实现这个网络假设, 将不同节点上的Docker 容器之间的互相访问先打通, 然后再运行 kubernetes .
同一个Pod 内的多个容器: loopback 回环网卡
各Pod 之间的 通讯: Overlay network
Pod 与 Service 之间的 通讯: 各节点的Iptables 规则
Flannel
- Flannel 是 CoreOS 团队针对 Kubernetes 设计的一个网络规划服务, 简单来说, 它的功能是让集群中的不同节点主机创建的Docker 容器都是具有 全集群唯一的虚拟IP地址.而且它还能在这些IP地址之间建立一个覆盖网络(Overlay Network), 通过这个覆盖网络, 将数据包原封不动的传递到目标容器内.
ETCD 之 Flannel 提供说明
- 存储管理 Flannel 可分配的IP地址段资源
- 监控ETCD 中每个Pod 的实际地址, 并在内存中建立维护Pod 节点路由表
同一个 Pod
内部通讯:
- 容器直接使用目标容器的ip访问,默认通过容器内部的eth0发送出去。
- 报文通过veth pair被发送到vethXXX。
- vethXXX是直接连接到虚拟交换机docker0的,报文通过虚拟bridge docker0发送出去。
- 查找路由表,外部容器ip的报文都会转发到flannel0虚拟网卡,这是一个P2P的虚拟网卡,然后报文就被转发到监听在另一端的flanneld。
- flanneld通过etcd维护了各个节点之间的路由表,把原来的报文UDP封装一层,通过配置的iface发送出去。
- 报文通过主机之间的网络找到目标主机。
- 报文继续往上,到传输层,交给监听在8285端口的flanneld程序处理。
- 数据被解包,然后发送给flannel0虚拟网卡。
- 查找路由表,发现对应容器的报文要交给docker0。
- docker0找到连到自己的容器,把报文发送过去。